package Leetcode.Stack;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Stack;

/**
 * @Author: kirito
 * @Date: 2024/4/21 13:07
 * @Description:
 * 移掉 K 位数字
 * 中等
 * 相关标签
 * 相关企业
 * 给你一个以字符串表示的非负整数 num 和一个整数 k ，移除这个数中的 k 位数字，使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
 *
 *
 * 示例 1 ：
 *
 * 输入：num = "1432219", k = 3
 * 输出："1219"
 * 解释：移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219 。
 * 示例 2 ：
 *
 * 输入：num = "10200", k = 1
 * 输出："200"
 * 解释：移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
 * 示例 3 ：
 *
 * 输入：num = "10", k = 2
 * 输出："0"
 * 解释：从原数字移除所有的数字，剩余为空就是 0 。
 *
 *
 * 提示：
 *
 * 1 <= k <= num.length <= 105
 * num 仅由若干位数字（0 - 9）组成
 * 除了 0 本身之外，num 不含任何前导零
 */

public class removeKdigits {
    public static void main(String[] args) {
        String num = "112";
        int k = 1;
        System.out.println(new removeKdigits().removeKdigits(num, k));
    }

    /**
     * 用单调栈  存一个递增序列
     * 前面尽可能的要小，后面如果比前面的要小就弹出去
     * 在弹的时候注意前导零的存在
     *
     * @param num
     * @param k
     * @return
     */
    public String removeKdigits(String num, int k) {
        int len = num.length();
        if (len == k) {
            return "0";
        }
        Stack<Character> stack = new Stack<>();
        int need_pop = k;
        for (int i = 0; i < len; i++) {
            if (need_pop > 0) {
                //1003456789
                while (!stack.isEmpty() && num.charAt(i) < stack.peek()) {
//                    if (stack.peek() == 0 && stack.size() == 1) {
//                        break;
//                    }
                    stack.pop();
                    need_pop--;
                    if (need_pop <= 0) {
                        break;
                    }
                }
            }

            stack.push(num.charAt(i));
        }
        System.out.println("stack:   "+stack.toString());
        int size = stack.size();
        //如果size大于len-k，那么还需要弹出最后size-k个元素
        if (size > len - k) {
            for (int i = 0; i < size-len + k; i++) {
                stack.pop();
            }
        }
        System.out.println("stack:   "+stack.toString());
        StringBuilder sb = new StringBuilder();
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }
        sb.reverse();
        System.out.println("string1:    " + sb);
        int index = 0;
        for (int i = 0; i < sb.length(); i++) {
            if (sb.charAt(i) != '0') {
                break;
            }
            index++;
        }
        String substring = sb.substring(index, sb.length());
        return substring.equals("")  ? "0" : substring;
    }

    public String removeKdigits2(String num, int k) {
        Deque<Character> deque = new LinkedList<Character>();
        int length = num.length();
        for (int i = 0; i < length; ++i) {
            char digit = num.charAt(i);
            while (!deque.isEmpty() && k > 0 && deque.peekLast() > digit) {
                deque.pollLast();
                k--;
            }
            deque.offerLast(digit);
        }

        for (int i = 0; i < k; ++i) {
            deque.pollLast();
        }

        StringBuilder ret = new StringBuilder();
        boolean leadingZero = true;
        while (!deque.isEmpty()) {
            char digit = deque.pollFirst();
            if (leadingZero && digit == '0') {
                continue;
            }
            leadingZero = false;
            ret.append(digit);
        }
        return ret.length() == 0 ? "0" : ret.toString();
    }

}
